/*
XPTracker - Alternative Agile Tracking Tool
Copyright (C) 2006-2009  Stephen Starkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package org.xptracker.web;

import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.security.action.Secure;
import net.sourceforge.stripes.validation.SimpleError;
import org.apache.commons.lang.StringUtils;
import org.xptracker.domain.*;
import org.xptracker.persistence.PersistenceManager;

import javax.servlet.http.HttpServletRequest;

@Secure(roles = "editor")
@UrlBinding("/Task.action")
public class TaskActionBean extends StandardActionBean {
  private Task task;

  public Task getTask() {
    return task;
  }

  public void setTask(Task task) {
    this.task = task;
  }

  @DefaultHandler
  public Resolution taskForm() {
    final HttpServletRequest request = getContext().getRequest();
    String storyId = param("storyId");
    if (StringUtils.isNotBlank(storyId)) {
      request.setAttribute("storyId", storyId);
      request.setAttribute("isStoryTask", true);
    }
    task = new Task();
    task.setOwner(getCurrentUser());
    return forwardToEdit(request, "Create");
  }

  @HandlesEvent("Edit")
  public Resolution loadTaskForEdit() {
    HttpServletRequest request = getContext().getRequest();
    Task task = loadTask();
    setTask(task);
    if (task instanceof StoryTask) {
      request.setAttribute("isStoryTask", true);
    }
    return forwardToEdit(request, "Update");
  }

  @HandlesEvent("Update")
  public Resolution updateTask() {
    task = getTask();
    return persistenceManager.inTransaction(new PersistenceManager.UpdateHandler<Resolution>() {
      public Resolution doUpdate(PersistenceManager.UpdateReceiver receiver) {
        Task updatedTask = loadTask(task.getId());
        updatedTask.setDescription(task.getDescription());
        updatedTask.setSummary(task.getSummary());
        if (WebUtil.isFit(updatedTask.getDescriptionContent())) {
          updatedTask.getDescriptionContent().setWikiStyle(WikiStyle.markdown);
        }
        if (updatedTask instanceof StoryTask) {
          String assignedUsername = param("taskOwner");
          User user = domain.loadUser(assignedUsername);
          updatedTask.setOwner(user);
        }
        updateTask(receiver, updatedTask, true);
        return success();
      }
    });
  }

  @HandlesEvent("Create")
  public Resolution createTask() {
    task = getTask();
    return persistenceManager.inTransaction(new PersistenceManager.UpdateHandler<Resolution>() {
      public Resolution doUpdate(PersistenceManager.UpdateReceiver receiver) {
        Story story = loadEntity(Story.class, param("storyId"));
        User storyTaskOwner = domain.loadUser(param("taskOwner"));
        StoryTask storyTask = new StoryTask(task.getSummary(), task.getDescription(), storyTaskOwner, story);
        receiver.insert(storyTask);
        story.getTasks().add(storyTask);
        receiver.update(story);
        return success();
      }
    });
  }

  @HandlesEvent("Delete")
  public Resolution deleteTask() {
    return persistenceManager.inTransaction(new PersistenceManager.UpdateHandler<Resolution>() {
      public Resolution doUpdate(PersistenceManager.UpdateReceiver receiver) {
        String taskId = param("id");
        StoryTask storyTask = loadEntity(StoryTask.class, taskId);
        Story story = storyTask.getStory();
        story.removeTask(storyTask);
        receiver.update(story);
        getContext().getRequest().setAttribute("story", story);
        return new ForwardResolution("/display/taskList.jsp");
      }
    });
  }

  @HandlesEvent("ToggleComplete")
  public Resolution completeTask() {
    return persistenceManager.inTransaction(new PersistenceManager.UpdateHandler<Resolution>() {
      public Resolution doUpdate(PersistenceManager.UpdateReceiver receiver) {
        String taskId = param("id");
        StoryTask task = loadEntity(StoryTask.class, taskId);
        if (task != null) {
          task.setComplete(Boolean.valueOf(param("complete")));
          updateTask(receiver, task, true);
        } else {
          getContext().getValidationErrors().add("", new SimpleError("No task found with ID " + taskId));
        }

        return new StreamingResolution("text/plain", String.valueOf(task.isComplete()));
      }
    });
  }

  private Resolution forwardToEdit(HttpServletRequest request, String type) {
    request.setAttribute("type", type);
    request.setAttribute("task", task);
    return new ForwardResolution("/editor/editTask.jsp");
  }


  private void updateTask(PersistenceManager.UpdateReceiver receiver, Task theTask, boolean updateParent) {
    assert theTask != null;
    receiver.update(theTask);
    if (updateParent && theTask instanceof StoryTask) {
      receiver.update(((StoryTask) theTask).getStory());
    }
  }

  private Task loadTask() {
    return loadTask(param("id"));
  }

  private Task loadTask(String id) {
    return loadEntity(Task.class, id);
  }

  private Resolution success() {
    return new ForwardResolution("/display/interstitialStoryUpdate.jsp");
  }
}

